/* ========================================
 *
 * Copyright YOUR COMPANY, THE YEAR
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF your company.
 *
 * ========================================
*/

#include "beachday.h"

uint32_t IREnabled = FALSE;

const struct IrCode * const * NACodes;
const struct IrCode * const * EUCodes;
uint8_t NACodeCount, EUCodeCount;
uint32_t LastTxCode = 0;

void InitIR( void )
{
    LastTxCode = 0;
    NACodes = GetNACodes();
    EUCodes = GetEUCodes();
    NACodeCount = GetNACodeCount();
    EUCodeCount = GetEUCodeCount();
}

uint32_t GetIRCode( void )
{
    
    return LastTxCode;
}

void xmitElement(uint16_t onTime, uint16_t offTime, uint16_t PWMCode)
{
    // setup PWM
    if(PWMCode != 0)
    {
        PWM_IR_WritePeriod(PWMCode);
        PWM_IR_WriteCompare(PWMCode / 2);
    }
    else
    {
        PWM_IR_WritePeriod(65000);
        PWM_IR_WriteCompare(65000);
    }
    
    // enable PWM
    PWM_IR_Start();
    
    CyDelayUs(onTime * 10);
    
    // disable PWM
    PWM_IR_Stop();
    
    CyDelayUs(offTime * 10);
}

void xmitIR(const struct IrCode * const IR)
{
    static uint8_t left = 0, bits = 0;
    uint8_t i, k, ti, id = 0;
    
    // for each pair in this code
    for(k = 0; k < IR->pairs; k++)
    {
        ti = 0;
        
        for(i = 0; i < IR->bits; i++)
        {
            if(left == 0) 
            {
                bits = IR->codes[id++];
                left = 8;
            }
            left--;
            ti |= (((bits >> left) & 1) << (IR->bits - 1 - i));
        }
        
        xmitElement(IR->times[2 * ti], IR->times[(2 * ti) + 1], IR->duration);
    }
    
    left = 0;
}

void TransmitCode(uint8_t code)
{
    if(code >= NACodeCount + EUCodeCount)
    {
        
        return;
    }
    
    if(code >= NACodeCount)
    {
        xmitIR(EUCodes[code - NACodeCount]);
    }
    else
    {
        xmitIR(NACodes[code]);
    }
}

uint32_t ServIR( void )
{
    static uint32_t st = IR_ST_OFF, Code = 0, Stamp = 0;
    LastTxCode = Code;
    
    switch(st)
    {
        case IR_ST_RUN:
            TransmitCode(Code++);
            if(Code >= NACodeCount + EUCodeCount)
            {
                LastTxCode = 0;
                IREnabled = FALSE;
                st = IR_ST_OFF;
            }
            else
            {
                Stamp = GetTick();
                st = IR_ST_IDLE;
            }
            break;
        case IR_ST_IDLE:
            if(GetTick() - Stamp > IR_CODE_DELAY)
            {
                st = IR_ST_RUN;
            }
            
            if(!IREnabled)
            {
                Code = 0;
                LastTxCode = 0;
                st = IR_ST_OFF;
            }
            break;
        default:
        case IR_ST_OFF:
            if(IREnabled)
            {
                Code = 0;
                st = IR_ST_RUN;
            }
            break;
    }
    
    return st;
}

void EnableIR( void )
{
    IREnabled = TRUE;
}

void DisableIR( void )
{
    IREnabled = FALSE;
}



/* [] END OF FILE */
